/*
 This file is derived off ELMAH:

http://code.google.com/p/elmah/

http://www.apache.org/licenses/LICENSE-2.0
 
 */

namespace SimpleErrorHandler
{
    using System;
    using System.Web;
    using CultureInfo = System.Globalization.CultureInfo;
    using Encoding = System.Text.Encoding;
    using Regex = System.Text.RegularExpressions.Regex;

    /// <summary>
    /// HTTP handler factory that dispenses handlers for rendering views and 
    /// resources needed to display the error log.
    /// </summary>
    public class ErrorLogPageFactory : IHttpHandlerFactory
    {
        /// <summary>
        /// Returns an object that implements the <see cref="IHttpHandler"/> interface and which is responsible for serving the request.
        /// </summary>
        /// <returns>
        /// A new <see cref="IHttpHandler"/> object that processes the request.
        /// </returns>
        public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {
            // In MVC requests, PathInfo isn't set - determine via Path..
            // e.g. "/admin/errors/detail" or "/admin/errors/"
            var match = Regex.Match(context.Request.Path, @"/?(?<resource>\w+)/?$");
            var resource = match.Success ? match.Groups["resource"].Value : "";

            switch (resource.ToLower(CultureInfo.InvariantCulture))
            {
                case "detail":
                    return new ErrorDetailPage();

                case "html":
                    return new ErrorHtmlPage();

                case "rss":
                    return new ErrorRssHandler();

                case "stylesheet":
                    return new ManifestResourceHandler("ErrorLog.css", "text/css", Encoding.GetEncoding("Windows-1252"));

                case "delete":
                    string errorId = context.Request.QueryString["id"] ?? "";
                    bool result = false;
                    if (errorId.Length >= 0)
                    {
                        result = ErrorLog.Default.DeleteError(errorId);
                    }
                    return new MessageHandler(@"<meta http-equiv=""refresh"" content=""0;URL=" + context.Request.Path.Replace("/delete", "") + @""">");

                case "protect":
                    // send back a "true" or "false" - this will be handled in javascript
                    return new MessageHandler(ErrorLog.Default.ProtectError(context.Request.QueryString["id"]).ToString());

                case "test":
                    throw new Exception("This is a test exception generated by " + (new PoweredBy()).ToString() + ". Please disregard.");

                case "testinner":
                    try
                    {
                        int a = 3;
                        int b = 0;
                        int x = a / b;
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("This is a wrapped exception generated by " + (new PoweredBy()).ToString() + ". Please disregard.", ex);
                    }
                    throw new Exception("This is a test exception generated by " + (new PoweredBy()).ToString() + ". Please disregard.");

                case "testignoredsame": throw new ArgumentException();
                case "testignoreddescendent": throw new ArgumentNullException();

                default:
                    return new ErrorLogPage();
            }
        }

        /// <summary>
        /// Enables the factory to reuse an existing handler instance.
        /// </summary>
        public virtual void ReleaseHandler(IHttpHandler handler)
        {
        }
    }
}
